﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading;
using HJ212_Common;
using HJ212_Protocol;
using HJT212_Protocol_DAL.DAO;
using HJT212_Protocol_DAL.Model;
using IPluginInterface;
using SailHero.Soft.ESB.Communication.ClientAndServer.Communication.EndPoints.Tcp;
using SailHero.Soft.ESB.Communication.ClientAndServer.Communication.Messages;
using SailHero.Soft.ESB.Communication.ClientAndServer.Communication.Messengers;
using SailHero.Soft.ESB.Communication.ClientAndServer.Server;
using Message = HJ212_Protocol.Message;

namespace HJT212_Protocol_Server
{
    public class ProtocolServer
    {
        #region 字段属性
        public IServer server;
        public bool IsHandleOffLine = ConfigOprater.GetNodeValue("IsHandleOffLine") == "1";

        public CommunicationServer ComuSrv { get; set; }
        /// <summary>
        /// 服务是否正在运行状态
        /// </summary>
        public bool IsRuning
        {

            get
            {
                if (server == null)
                {
                    return false;
                }
                else
                {
                    return server.IsRuning();
                }
            }
        }

        private const string pingQN = "20000000000000001";

        private log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        private int MaxConnNum = Convert.ToInt32(ConfigOprater.GetNodeValue("MaxConnNum"));

        /// <summary>
        ///是否对连接的Socket检测登录包，如果不检测，
        ///则按接收到消息中MN确定数采仪标示
        ///默认是 1 检测
        /// </summary>
        private int IsMnCheck = Convert.ToInt32(ConfigOprater.GetNodeValue("IsMnCheck"));



        private int PingType = Convert.ToInt32(ConfigOprater.GetNodeValue("PingType"));

        /// <summary>
        /// 处理需要自动保存数据的
        /// </summary>
        private Dictionary<string, string> ToHandeAutoSaveDataDicts = new Dictionary<string, string>();
        /// <summary>
        /// 处理需要自动保存数据的
        /// </summary>
        private List<string> AutoSaveDataDicts = new List<string>() { "2011", "2031", "2051", "2061" };


        private ServerPluginHandler plugHandler = new ServerPluginHandler();
        #endregion

        #region 事件
        private void server_ClientConnected(object sender, ServerClientEventArgs e)
        {
            try
            {
                #region 判断是否超过最大连接数
                if (server.Clients.Count > MaxConnNum)
                {
                    ComuSrv.showTraceMsg("服务超出设置的最大连接数，强制剔除新进链接:" + e.Client.ClientSocket.RemoteEndPoint);
                    e.Client.Disconnect();
                    return;
                }
                ComuSrv.showTraceMsg("客户端已连接，等待登录 From:" + e.Client.ClientSocket.RemoteEndPoint);
                #endregion
                e.Client.StopPing(PingType);
                e.Client.MessageReceived += Client_MessageReceived;
                e.Client.ClientLogin += Client_ClientLogin;
            }
            catch (Exception ex)
            {
                log.Error("出现异常", ex); 
            }
        } 
        private void server_ClientDisconnected(object sender, ServerClientEventArgs e)
        {
            try
            {
                //if (!string.IsNullOrEmpty(e.Client.MN))
                //{
                //    ComuSrv.showTraceMsg("客户端已断开，From:" + e.Client.MN);
                //}
                //else
                //{
                //    ComuSrv.showTraceMsg("客户端已断开，未登录:" + e.Client.ClientId);
                //}
                //ComuSrv.showTraceMsg("客户端总数为:" + server.Clients.Count);
                ParameterizedThreadStart Start = new ParameterizedThreadStart(o => ShowOnlineClients());
                Thread Thrd = new Thread(Start);
                Thrd.Start();
            }
            catch (Exception ex)
            {
                log.Error("出现异常", ex);
            }
        }
        private void Client_ClientLogin(object sender, MessageEventArgs e)
        {
            try 
            {
                IServerClient srvclient = (IServerClient)(sender);
                OnLogin(srvclient, e.Message);
            }
            catch (Exception ex)
            {
                log.Error("出现异常", ex);
            }

        }

        private void Client_MessageReceived(object sender, MessageEventArgs e)
        {
            try
            {
                IServerClient srvclnt = (IServerClient)sender;
                ParameterizedThreadStart Start = new ParameterizedThreadStart(o => OnMsgReceived(srvclnt, e.Message));
                Thread Thrd = new Thread(Start);
                Thrd.Start();
            }
            catch (Exception ex)
            {
                log.Error("出现异常", ex);
                //throw;
            }

        }
        #endregion

        #region 方法函数

        #region 公有

        /// <summary>
        /// 初始化
        /// </summary>
        private void Init()
        {
            try
            {
                string _port = ConfigOprater.GetNodeValue("SrvPort");
                server = ServerFactory.CreateServer(new ESBTcpEndPoint(Convert.ToInt32(_port)));
                server.WireProtocolFactory = new MyWireProtocolFactory(); //自定义通讯协议工厂!
                server.ClientConnected += server_ClientConnected;
                server.ClientDisconnected += server_ClientDisconnected;
                UpdateOffLineAll();
                plugHandler.Init();

            }
            catch (Exception ex)
            {
                log.Error("出现异常", ex);
            }
        }
        /// <summary>
        /// 初始化
        /// </summary>
        public void Init(CommunicationServer cmSrv)
        {
            try
            {
                Init();
                ComuSrv = cmSrv;
                cmSrv.ClntSrv = this;
            }
            catch (Exception ex)
            {
                log.Error("出现异常", ex);
            }
        }

        /// <summary>
        /// 停止
        /// </summary>
        public void Stop()
        {
            try
            {
                if (IsRuning)
                {
                    UpdateOffLineAll();
                    server.Stop();
                }

            }
            catch (Exception ex)
            {

                log.Error("出现异常", ex);
            }
        }


        /// <summary>
        /// 停止
        /// </summary>
        public void Start()
        {
            try
            {
                if (!IsRuning)
                {
                    (new Thread(new ThreadStart(server.Start))).Start();
                }
            }
            catch (Exception ex)
            {

                log.Error("出现异常", ex);
            }
        }


        #endregion


        #region 私有

        public void UpdateOffLineAll()
        {
            try
            {

                ClientDao clntDao = new ClientDao();
                clntDao.UpdateAllOffOnline();
            }
            catch (Exception ex)
            {
                log.Error("出现异常", ex);
            }
        }
        /// <summary>
        /// 执行登录事件
        /// </summary>
        /// <param name="srvClient">登录进来的客户端</param>
        /// <param name="msg">登录的信息</param>
        /// <param name="isChkPwd">是否检测登录信息包的密码</param>
        private void OnLogin(IServerClient srvClient, IMessage msg, bool isChkPwd = true)
        {

            try
            {
                IServerClient srvclient = (IServerClient)(srvClient);
                var oldClients = server.Clients.GetAllItems().Where(itm =>
                    itm.MN == srvclient.MN && itm.ClientId != srvclient.ClientId);
                if (oldClients != null && oldClients.Count() > 0)
                {
                    #region 剔除相同MN的客户端
                    IServerClient clnt = oldClients.First();
                    string msg0 =
                        @"MN号为：{0} 的现场机存在可疑异常，剔除了已有在线列表的相同MN号的现场机，
                                    已有现场机的RemotEndpoint：{1}，后来登录的RemotEndPoint为：{2} ";
                    msg0 = string.Format(msg0, srvclient.MN, clnt.ClientSocket.RemoteEndPoint, srvclient.RemoteEndPoint);
                    //log.Warn(msg);
                    if (ComuSrv.showTraceMsg != null)
                    {
                        ComuSrv.showTraceMsg(msg0);
                    }
                    oldClients.ToList().ForEach(itm => itm.Disconnect());
                    #endregion
                }
                ShowClients(srvClient, msg, isChkPwd);
                if (IsHandleOffLine)
                {
                    ParameterizedThreadStart Start = new ParameterizedThreadStart(o => HandleOfflineMsg(srvClient, msg));
                    Thread Thrd = new Thread(Start);
                    Thrd.Start();
                }
                #region 显示跟踪信息
                TextMessage Tmsg = (TextMessage)msg;
                if (Tmsg.QN != pingQN && Tmsg.CN == "9021" && ComuSrv.showTraceMsg != null)
                {
                    string msg0 = "From({0}):{1}";
                    msg0 = string.Format(msg0, srvClient.MN, Tmsg.Text);
                    ComuSrv.showTraceMsg(msg0);
                }
                #endregion
            }
            catch (Exception ex)
            {

                log.Error("出现异常", ex);
            }
        }


        private void OnMsgReceived(IServerClient clent, IMessage Msg)
        {
            try
            {
                TextMessage Tmsg = (TextMessage)Msg;

                #region 超时重发处理
                if (Tmsg != null && !string.IsNullOrEmpty(Tmsg.QN))
                {
                    int v = -1;
                    v = SendMessageTimout.DictMessages[Tmsg.QN];
                    if (v == 1)
                    {
                        SendMessageTimout.DictMessages.Remove(Tmsg.QN);
                        SendMessageTimout.DictMessages[Tmsg.QN] = 2;
                        ManualResetEventSlim WaitEvent = SendMessageTimout.DictMessagesWaitEvent[Tmsg.QN];
                        if (WaitEvent != null)
                        {
                            WaitEvent.Set();
                        }
                    }
                }
                #endregion

                #region 检测发送非法消息
                if (Tmsg.MN != null && Tmsg.MN != clent.MN)
                {
                    if (IsMnCheck == 0)
                    {
                        if (!string.IsNullOrEmpty(clent.MN))
                        {
                            string msg0 =
                                @"MN号为：{0} 的现场机,由于服务为免登录注册包登录，
                                 所以自动替换为新的MN标示号：{1}，密码沿用之前的密码！ ";
                            msg0 = string.Format(msg0, clent.MN, Tmsg.MN);
                            //log.Warn(msg0);
                            if (ComuSrv.showTraceMsg != null)
                            {
                                ComuSrv.showTraceMsg(msg0);
                            }
                        }

                        clent.MN = Tmsg.MN;
                        OnLogin(clent, Tmsg, false);//不检测登录密码
                    }
                    else
                    {
                        string msg = "客户端发送的消息有异常(消息的MN与客户端登录注册的MN不相同)，" +
                                     "消息的MN为：{0},客户端表示的MN为：{1}，发送的消息内容为：{2}," +
                                     "客户端的发送指令的操作视为非法操作，将强制踢出";
                        msg = string.Format(msg, Tmsg.MN, clent.MN, Tmsg.Text);
                        if (ComuSrv.showTraceMsg != null)
                        {
                            ComuSrv.showTraceMsg(msg);
                        }
                        clent.Disconnect();
                        return;
                    }
                }
                #endregion

                #region 显示跟踪信息
                if (ComuSrv.showTraceMsg != null)
                {
                    string msg = "From({0}):{1}";
                    msg = string.Format(msg, clent.MN, Tmsg.Text);
                    ComuSrv.showTraceMsg(msg);
                }
                #endregion

                #region 实时上报数据存储
                SaveAutoUpLoadData(Tmsg);
                #endregion

                #region 转发

                MessageModel mModel = ConvertToIMsglFromMsg(Tmsg);

                if (string.IsNullOrEmpty(Tmsg.QN))//QN为空的时候写入return表中
                {
                    if (!AutoSaveDataDicts.Contains(Tmsg.CN))
                    {
                        AddToReturnTB(Tmsg);
                        braodCastToEvery(Tmsg);
                    }
                }
                else
                {
                    MsgCacheDao mcacheDao = new MsgCacheDao();
                    string CMN = mcacheDao.FindMNByQNFromCache(Tmsg.QN);
                    if (!string.IsNullOrEmpty(CMN))
                    {
                        var lstSClients = ComuSrv.HostSrv.server.Clients.GetAllItems().Where(
                            delegate(IServerClient itm)
                            {
                                return itm.MN.Trim() == CMN;
                            });
                        if (lstSClients != null && lstSClients.Count() > 0)
                        {
                            IServerClient itm = lstSClients.First();
                            itm.SendMessage(Tmsg);
                            if (ComuSrv.showHostTraceMsg != null)
                            {
                                string msg = "To({0}):{1}";
                                msg = string.Format(msg, itm.ClientSocket.RemoteEndPoint, Tmsg.Text);
                                ComuSrv.showHostTraceMsg(msg);
                            }

                        }
                        else ///todo:不在线的缓存处理 写入return表，发送给指定的webservice
                        {
                            AddToReturnTB(Tmsg);
                            plugHandler.InvokeOffLineMessageRecived(mModel);
                            #region 发离线消息回执
                            CMD_SendDao dao = new CMD_SendDao();
                            string content = "";
                            string sid = dao.GetSidByQn(Tmsg.QN, out content);
                            plugHandler.InvokeOffLineMessageNote(
                                "仪器反控",
                                string.Format("{0}", content),
                                string.Format("{0}", sid)
                                );
                            #endregion
                        }
                    }
                    else
                    {
                        if (!AutoSaveDataDicts.Contains(Tmsg.CN))
                        {
                            AddToReturnTB(Tmsg);
                            plugHandler.InvokeOffLineMessageRecived(mModel);
                            //braodCastToEvery(Tmsg);
                            if (Tmsg.CN == "2072")
                            {
                                plugHandler.InvokeOnAlertDesired(mModel);
                            }
                            ///发送警报处理
                        }
                    }
                }

                plugHandler.InvokeMessageRecived(mModel);

                #endregion

            }
            catch (Exception ex)
            {

                log.Error("出现异常", ex);
            }
        }

        /// <summary>
        /// 广播数据给其他客户端
        /// </summary>
        /// <param name="Tmsg">待广播的数据</param>
        private void braodCastToEvery(TextMessage Tmsg)
        {
            #region 广播给在线的客户端
            try
            {
                if (Tmsg == null) return;
                List<IServerClient> lstHost = ComuSrv.HostSrv.server.Clients.GetAllItems();
                lstHost.ForEach(itm =>
                {
                    try
                    {
                        if (ComuSrv.showHostTraceMsg != null)
                        {
                            string msg = "To({0}):{1}";
                            msg = string.Format(msg, itm.ClientSocket.RemoteEndPoint, Tmsg.Text);
                            ComuSrv.showHostTraceMsg(msg);
                        }
                        itm.SendMessage(Tmsg);
                    }
                    catch (Exception ex)
                    {
                        log.Error("出现异常", ex);
                    }
                });
            }
            catch (Exception ex)
            {
                log.Error("出现异常", ex);
            }
            #endregion
        }

        private void AddToReturnTB(TextMessage Tmsg)
        {
            try
            {
                if (Tmsg == null) return;
                CMD_ReturnModel mdl = ConvertToRMdlFromMsg(Tmsg);
                if (mdl != null)
                {
                    CMD_ReturnDao returnDao = new CMD_ReturnDao();
                    returnDao.AddCMDToCache(mdl);
                }
            }
            catch (Exception ex)
            {
                log.Error("出现异常", ex);
            }
        }

        /// <summary>
        /// 显示客户端列表数据至列表控件
        /// </summary>
        /// <param name="clients">客户端列表</param>
        /// <param name="msg">登录的消息</param>
        /// <param name="isChkPwd">是否检测登录的密码</param>
        private void ShowClients(IServerClient srvClient, IMessage msg, bool isChkPwd = true)
        {

            try
            {
                if (srvClient == null) return;
                TextMessage Tmsg = (TextMessage)msg;
                if (msg == null || server.Clients.Count <= 0)
                {
                    return;
                }

                if (string.IsNullOrEmpty(srvClient.MN))
                {
                    //非法客户端，强制踢出
                    srvClient.Disconnect();
                    return;
                }
                if (ComuSrv.LstClients == null || ComuSrv.LstClients.Count <= 0)
                {
                    // InitConn();
                    ClientDao clntDao = new ClientDao();
                    ComuSrv.LstClients = clntDao.GetDbClientList();
                }
                var clnts = ComuSrv.LstClients.Where(itm => itm.MN == srvClient.MN && itm.PW == srvClient.PW);
                if (!isChkPwd)
                {
                    clnts = ComuSrv.LstClients.Where(itm => itm.MN == srvClient.MN);
                }
                if (clnts == null || clnts.Count() <= 0)
                {
                    //非法客户端，强制踢出
                    srvClient.Disconnect();
                    return;
                }
                ShowOnlineClients();
            }
            catch (Exception ex)
            {

                log.Error("出现异常", ex);
            }
        }

        /// <summary>
        /// 显示所有在线的客户端
        /// </summary>
        private void ShowOnlineClients()
        {
            try
            {
                ComuSrv.LstClients.ForEach(itm => itm.OnLineState = 0);
                List<IServerClient> List = server.Clients.GetAllItems();
                foreach (IServerClient scsServerClient in List)
                {
                    var source = ComuSrv.LstClients.Where(itm => itm.MN == scsServerClient.MN);

                    if (source != null && source.Count() > 0)
                    {
                        source.First().OnLineState = 2;
                    }


                }
                foreach (ClientModel mdl in ComuSrv.LstClients.Where(itm => !string.IsNullOrEmpty(itm.MN)))
                {
                    ClientDao clntDao = new ClientDao();
                    clntDao.UpdateOnlineState(mdl.MN, mdl.OnLineState);
                }

                if (ComuSrv.showOnline != null)
                {
                    ComuSrv.showOnline(ComuSrv.LstClients);
                }
            }
            catch (Exception ex)
            {

                log.Error("出现异常", ex);
            }
        }

        /// <summary>
        /// 处理指定客户端登录时的指令缓存
        /// </summary>
        /// <param name="srvClient">客户端端对象</param>
        /// <param name="msg">消息</param>
        private void HandleOfflineMsg(IServerClient srvClient, IMessage msg)
        {
            try
            {

                List<CMD_SendModel> lst = new List<CMD_SendModel>();
                int pNum = 1, psize = 10;
                do
                {
                    CMD_SendDao sendDao = new CMD_SendDao();
                    lst = sendDao.GetSendCMDByMN(srvClient.MN, psize, pNum);
                    if (lst == null)
                    {
                        break;
                    }
                    foreach (CMD_SendModel Model in lst)
                    {
                        TextMessage Tmsg = ConvertTomsgFromMdl(Model);
                        if (Tmsg != null)
                        {
                            SendMessage(srvClient, Tmsg);
                        }
                        sendDao.UpdateSendState(Model);
                    }
                    pNum++;
                    lst = sendDao.GetSendCMDByMN(srvClient.MN, psize, pNum);
                } while (lst != null && lst.Count > 0);
            }
            catch (Exception ex)
            {

                log.Error("出现异常", ex);
            }
        }


        private TextMessage ConvertTomsgFromMdl(CMD_SendModel mdl)
        {
            if (mdl == null) return null;
            try
            {
                string cmd = "";
                if (mdl.QN != null)
                {
                    cmd = cmd + "QN=" + mdl.QN + ";";
                }
                if (mdl.ST != null)
                {
                    cmd = cmd + "ST=" + mdl.ST + ";";
                }
                if (mdl.MN != null)
                {
                    cmd = cmd + "MN=" + mdl.MN + ";";
                }
                if (mdl.CN != null)
                {
                    cmd = cmd + "CN=" + mdl.CN + ";";
                }
                if (mdl.PW != null)
                {
                    cmd = cmd + "PW=" + mdl.PW + ";";
                }
                if (mdl.CP != null)
                {
                    cmd = cmd + "CP=&&" + mdl.QN + "&&";
                }
                TextMessage msg = new TextMessage(cmd);
                return msg;

            }
            catch (Exception ex)
            {

                log.Error("出现异常", ex);
            }

            return null;
        }


        private CMD_ReturnModel ConvertToRMdlFromMsg(TextMessage mesg)
        {
            if (mesg == null) return null;
            try
            {
                string content = mesg.Text.ToUpper().Replace(" ", "").Replace("　", "");
                string ExeRtn0 = "", QNRtn0 = "";
                int k = content.IndexOf("EXERTN=");
                if (k >= 0)
                {
                    ExeRtn0 = content.Substring(k + 7, 3);//ExeRtn的宽度为N3
                }
                int j = content.IndexOf("QNRTN=");
                if (j >= 0)
                {
                    QNRtn0 = content.Substring(j + 6, 3);//QNRtn的宽度为N3
                }
                CMD_ReturnModel cmdM = new CMD_ReturnModel()
                {
                    QN = mesg.QN,
                    MN = mesg.MN,
                    PW = mesg.PW,
                    CN = mesg.CN,
                    CP = mesg.CP,
                    ST = mesg.ST,
                    ExeRtn = handleWidthNstr(ExeRtn0),
                    QNRtn = handleWidthNstr(QNRtn0),
                    isDisp = 1
                };
                return cmdM;

            }
            catch (Exception ex)
            {

                log.Error("出现异常", ex);
            }

            return null;
        }


        private MessageModel ConvertToIMsglFromMsg(TextMessage mesg)
        {
            if (mesg == null) return null;
            try
            {
                string content = mesg.Text.ToUpper().Replace(" ", "").Replace("　", "");
                string ExeRtn0 = "", QNRtn0 = "";
                int k = content.IndexOf("EXERTN=");
                if (k >= 0)
                {
                    ExeRtn0 = content.Substring(k + 7, 3);//ExeRtn的宽度为N3
                }
                int j = content.IndexOf("QNRTN=");
                if (j >= 0)
                {
                    QNRtn0 = content.Substring(j + 6, 3);//QNRtn的宽度为N3
                }
                MessageModel cmdM = new MessageModel()
                {
                    QN = mesg.QN,
                    MN = mesg.MN,
                    PW = mesg.PW,
                    CN = mesg.CN,
                    CP = mesg.CP,
                    ST = mesg.ST,
                    ExeRtn = handleWidthNstr(ExeRtn0),
                    QNRtn = handleWidthNstr(QNRtn0)
                };
                return cmdM;

            }
            catch (Exception ex)
            {

                log.Error("出现异常", ex);
            }

            return null;
        }
        /// <summary>
        /// 处理指定宽度的数字字串
        /// </summary>
        private string handleWidthNstr(string str)
        {
            if (string.IsNullOrEmpty(str)) return null;
            string strs = str;
            int dd = 0;
            for (int i = 0; i < str.Length; i++)
            {
                if (isNumberic(strs, out dd))
                {
                    break;
                }
                else
                {
                    strs = strs.Substring(0, strs.Length - 1);
                }
            }
            return dd.ToString();
        }

        private bool isNumberic(string message, out int result)
        {
            System.Text.RegularExpressions.Regex rex =
            new System.Text.RegularExpressions.Regex(@"^\d+$");
            result = -1;
            if (rex.IsMatch(message))
            {
                result = int.Parse(message);
                return true;
            }
            else
                return false;
        }


        /// <summary>
        /// Sends a message to the client.
        /// </summary>
        /// <param name="message">Message to be sent</param>
        public void SendMessage(IServerClient clnt, IMessage message)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(o => SendMsg(clnt, message)));
        }


        private void SendMsg(IServerClient clnt, IMessage message)
        {
            try
            {
                int sentTimes = 0;
                bool isSending = true;
                TextMessage Tmsg = (TextMessage)message;
                if (Tmsg != null && !string.IsNullOrEmpty(Tmsg.QN))
                {
                    if (!SendMessageTimout.DictMessages.ContainsKey(Tmsg.QN))
                    {
                        SendMessageTimout.DictMessages[Tmsg.QN] = 1;
                    }
                    int v = 0;
                    v = SendMessageTimout.DictMessages[Tmsg.QN];
                    while (isSending && sentTimes < ComuSrv.SendTimes && v == 1)
                    {
                        try
                        {
                            sentTimes++;
                            if (ComuSrv.showTraceMsg != null)
                            {
                                string msg = "To({0}):{1}";
                                msg = string.Format(msg, clnt.MN, Tmsg.Text);
                                ComuSrv.showTraceMsg(msg);
                            }
                            clnt.ClientSocket.SendTimeout = ComuSrv.SendTimeOut * 1000;
                            clnt.SendMessage(message);
                            ManualResetEventSlim WaitEvent = new ManualResetEventSlim(false);
                            SendMessageTimout.DictMessagesWaitEvent[Tmsg.QN] = WaitEvent;
                            //Thread.Sleep(ComuSrv.SendTimeOut * 1000); //超时时间
                            WaitEvent.Wait(ComuSrv.SendTimeOut * 1000);
                            v = SendMessageTimout.DictMessages[Tmsg.QN];
                            isSending = v == 1;
                        }
                        catch (Exception ex) //捕获到超时或者其他异常的时候重发指定次数
                        {
                            isSending = true;
                        }
                    }
                    SendMessageTimout.DictMessages.Remove(Tmsg.QN);
                    SendMessageTimout.DictMessagesWaitEvent.Remove(Tmsg.QN);
                    if (isSending)
                    {
                        Client_MessageSentTimeOut(Tmsg);
                    }
                }
            }
            catch (Exception ex)
            {
                log.Error("出现异常", ex);
            }
        }

        /// <summary>
        /// todo:需要处理MessageId的问题
        /// </summary>
        /// <param name="clnt"></param>
        /// <param name="message"></param>
        private void SendMsg_Old(IServerClient clnt, IMessage message)
        {
            try
            {
                int sentTimes = 0;
                bool isSending = true;
                TextMessage Tmsg = (TextMessage)message;
                if (Tmsg != null && !string.IsNullOrEmpty(Tmsg.QN))
                {

                    while (isSending & sentTimes < ComuSrv.SendTimes)
                    {
                        try
                        {
                            sentTimes++;
                            using (var requestReplyMessenger = new RequestReplyMessenger<IServerClient>(clnt))
                            {
                                requestReplyMessenger.MessageReciverHandler += requestReplyMessenger_MessageReciverHandler;
                                requestReplyMessenger.Start(); //Start request/reply messenger
                                //Send user message to the server and get response
                                if (ComuSrv.SendTimeOut <= 0 && ComuSrv.SendTimeOut > 30)
                                {
                                    ComuSrv.SendTimeOut = 10;
                                }
                                var response =
                                    requestReplyMessenger.SendMessageAndWaitForResponse(message,
                                    ComuSrv.SendTimeOut * 1000);
                                isSending = false;
                            }
                        }
                        catch (Exception ex)
                        {
                            isSending = true;
                        }
                    }
                    if (isSending)
                    {
                        Client_MessageSentTimeOut(Tmsg);
                    }
                }
                else
                {
                    log.Error("出现异常", new Exception("消息未带QN:" + Tmsg.Text));
                }

            }
            catch (Exception ex)
            {
                log.Error("出现异常", ex);
            }
        }

        private void requestReplyMessenger_MessageReciverHandler(object sender, MessageEventArgs e)
        {
            try
            {
                //通过Msg的QN获取请求消息的MessageId
                IServerClient clnt = (IServerClient)sender;
                TextMessage Tmsg = (TextMessage)e.Message;
                MsgCacheDao mcacheDao = new MsgCacheDao();
                Tmsg.RepliedMessageId = mcacheDao.GetMessageIdByQn(Tmsg.QN);
                e.Message = Tmsg;
                OnMsgReceived(clnt, e.Message);
                /// todo:绑定两次的问题
            }
            catch (Exception ex)
            {
                log.Error("出现异常", ex);
            }
        }

        private void Client_MessageSentTimeOut(IMessage message)
        {
            try
            {
                TextMessage Tmsg = (TextMessage)message;
                if (Tmsg == null) return;
                log.Info("指令发送超时：" + ((TextMessage)message).Text);
                CMD_SendModel mdl = ComuSrv.ConvertToMdlFromMsg(Tmsg);
                if (mdl != null)
                {
                    CMD_SendDao sendDao = new CMD_SendDao();
                    sendDao.AddCMDToCache(mdl);
                }
            }
            catch (Exception ex)
            {
                log.Error("出现异常", ex);
            }
        }


        /// <summary>
        /// 保存自动上报的数据
        /// </summary>
        /// <param name="Tmsg">上报上来的数据</param>
        private void SaveAutoUpLoadData(TextMessage Tmsg)
        {
            try
            {
                if (Tmsg == null) return;
                string cn = Tmsg.CN;
                string cp = Tmsg.CP;
                if (string.IsNullOrEmpty(cn) || string.IsNullOrEmpty(Tmsg.MN) ||
                    string.IsNullOrEmpty(cp) || !AutoSaveDataDicts.Contains(cn)) return;

                if (cn == "2011")
                {
                    plugHandler.InvokeRunTimeMessageRecived(ConvertToIMsglFromMsg(Tmsg));
                }
                else
                {
                    plugHandler.InvokeHistoryMessageRecived(ConvertToIMsglFromMsg(Tmsg));
                }
                SaveAutoUploadDataDao dao = new SaveAutoUploadDataDao();
                dao.SaveAutoUpLoadData(Tmsg);
            }
            catch (Exception ex)
            {
                log.Error("出现异常", ex);
            }
        }



        #endregion


        #endregion
    }
}
